cmake_minimum_required(VERSION 3.0)
project(log4x)

message(STATUS "cmake default debug CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS_DEBUG}")
message(STATUS "cmake default release CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS_RELEASE}")

SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -D_DEBUG")
#SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}")

#option(BUILD_SHARED_LIBS "Build liblog4x as a shared library." OFF)
#option(BUILD_SHARED_LIBS "Build liblog4x as a shared library." ON)
option(BUILD_STATIC_LIBS "Build liblog4x static library." ON)

# PROJECT_BINARY_DIR and PROJECT_SOURCE_DIR are the variables of cmake
set(LOG4X_SRC_DIR ${PROJECT_SOURCE_DIR}/src)

set(PROJECT_ROOT_DIR ${PROJECT_SOURCE_DIR})

##################### start functions ######################
# Set variable named ${VAR_NAME} to value ${VALUE}, see Jsoncpp CMakeLists.txt
function(set_using_dynamic_name VAR_NAME VALUE)
    set( "${VAR_NAME}" "${VALUE}" PARENT_SCOPE)
endfunction()
##################### end functions ########################

##################### start macros #########################
macro(source_group_by_dir SOURCE_FILES)
    if(MSVC)
        foreach(SOURCE_CUR_FILE ${${SOURCE_FILES}})
            message(STATUS "${SOURCE_CUR_FILE}")
            string(REGEX REPLACE "(.*/)" "" SOURCE_CUR_FILE_NAME ${SOURCE_CUR_FILE})
            message(STATUS "SOURCE_CUR_FILE_NAME: ${SOURCE_CUR_FILE_NAME}")
            string(REGEX REPLACE "/${SOURCE_CUR_FILE_NAME}" "" SOURCE_GROUP_PATH ${SOURCE_CUR_FILE})
            message(STATUS "SOURCE_GROUP_PATH: ${SOURCE_GROUP_PATH}")

            string(REGEX REPLACE "${PROJECT_ROOT_DIR}/" "" SOURCE_GROUP_NAME ${SOURCE_GROUP_PATH})
            message(STATUS "PROJECT_ROOT_DIR: ${PROJECT_ROOT_DIR} SOURCE_GROUP_NAME: ${SOURCE_GROUP_NAME}")

            string(COMPARE EQUAL ${SOURCE_CUR_FILE_NAME} ${SOURCE_GROUP_NAME} NOGROUP)
            if(NOGROUP)
                set(SOURCE_GROUP_NAME "/")
            endif()
            source_group(${SOURCE_GROUP_NAME} FILES ${SOURCE_CUR_FILE})

        endforeach(SOURCE_CUR_FILE)
    endif(MSVC)
endmacro(source_group_by_dir)

macro(core_parse_version VERSION_TEXT OUPUT_PREFIX)
    set(VERSION_REGEX "[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+(-[a-zA-Z0-9_]+)?")
    if( ${VERSION_TEXT} MATCHES ${VERSION_REGEX} )
        string(REGEX MATCHALL "[0-9]+|-([A-Za-z0-9_]+)" VERSION_PARTS ${VERSION_TEXT})
        list(GET VERSION_PARTS 0 ${OUPUT_PREFIX}_PART0)
        list(GET VERSION_PARTS 1 ${OUPUT_PREFIX}_PART1)
        list(GET VERSION_PARTS 2 ${OUPUT_PREFIX}_PART2)
        list(GET VERSION_PARTS 3 ${OUPUT_PREFIX}_PART3)
        set_using_dynamic_name( "${OUPUT_PREFIX}_FOUND" TRUE )
    else()
        set_using_dynamic_name( "${OUPUT_PREFIX}_FOUND" FALSE )
    endif()
endmacro()
##################### end macros ###########################

message(STATUS "C++ flags have ${CMAKE_CXX_FLAGS}")

string(TIMESTAMP VERSION_BUILD_PTS %Y%m%d%H%M%S)
message(STATUS "Build timestamp: ${VERSION_BUILD_PTS}")

find_file(HAVE_GIT NAMES .git PATHS ${CMAKE_CURRENT_SOURCE_DIR})
message(STATUS "HAVE_GIT: ${HAVE_GIT}")

if(HAVE_GIT)
    exec_program(
        "git"
        ${CMAKE_CURRENT_SOURCE_DIR}
        ARGS "log --format=%h -1"
        OUTPUT_VARIABLE VERSION_SHA1)

    exec_program(
        "git"
        ${CMAKE_CURRENT_SOURCE_DIR}
        ARGS "rev-list --tags --max-count=1"
        OUTPUT_VARIABLE VERSION_TAG_SHA1)

    exec_program(
        "git"
        ${CMAKE_CURRENT_SOURCE_DIR}
        # ARGS "describe --tags ${VERSION_TAG_SHA1}"
        ARGS "describe --tags --abbrev=4 ${VERSION_SHA1}"
        OUTPUT_VARIABLE VERSION_TAG_DESCRIBE)

    set(VERSION_TAG_REGEX "v[0-9]+.[0-9]+.[0-9]+.[0-9]+-[0-9]+")
    if(${VERSION_TAG_DESCRIBE} MATCHES ${VERSION_TAG_REGEX})
        string (REGEX REPLACE ${VERSION_TAG_REGEX} ""
            TAG_SHA1_PREFIX
            ${VERSION_TAG_DESCRIBE})

        message(STATUS "VERSION_TAG_DESCRIBE: ${VERSION_TAG_DESCRIBE}")
        string (REGEX REPLACE "${TAG_SHA1_PREFIX}" ""
            VERSION_TAG
            ${VERSION_TAG_DESCRIBE})
    else()
        set(VERSION_TAG ${VERSION_TAG_DESCRIBE})
    endif()
    message(STATUS "VERSION_TAG: ${VERSION_TAG} VERSION_SHA1: ${VERSION_SHA1}")

    core_parse_version(${VERSION_TAG} VERSION)

    if(NOT VERSION_FOUND)
        message(FATAL_ERROR "Failed to parse version tag string properly. Expect v[1-9].[0-9].[0-9].[0-9]-[a-zA-Z0-9]")
    endif()

    message(STATUS "Core Version: ${VERSION_PART0}.${VERSION_PART1}.${VERSION_PART2}.${VERSION_PART3}")

    file(WRITE ${PROJECT_ROOT_DIR}/version.h
        "#ifndef __VERSION_H__\n"
        "#define __VERSION_H__\n"
        "#define VERSION_BUILD_PTS\t\t\"${VERSION_BUILD_PTS}\"\n"
        "#define VERSION_TAG      \t\t\"${VERSION_TAG}\"\n"
        "#define VERSION_SHA1     \t\t\"${VERSION_SHA1}\"\n"
        "#define VERSION_COPYRIGHT\t\t\"Contron, Ltd. <caiwang213@qq.com>\"\n\n"
        "#define VERSION_PART0    \t\t${VERSION_PART0}\n"
        "#define VERSION_PART1    \t\t${VERSION_PART1}\n"
        "#define VERSION_PART2    \t\t${VERSION_PART2}\n"
        "#define VERSION_PART3    \t\t${VERSION_PART3}\n\n"

        "#ifndef VERSION_COMPILER\n"
        "#define VERSION_COMPILER \t\t${CMAKE_CXX_COMPILER_ID}-${CMAKE_CXX_COMPILER_VERSION}\n"
        "#endif\n\n"

        "#define _TOSTR(s)        \t\t#s\n"
        "#define _S(s)            \t\t_TOSTR(s)\n"
        "#endif\n"
        )
else()
    file(READ ${PROJECT_ROOT_DIR}/version.h VERSION_H_CONTENT)
    string (REGEX REPLACE
        "#define VERSION_BUILD_PTS\t\t\"[^\"]*\""
        "#define VERSION_BUILD_PTS\t\t\"${VERSION_BUILD_PTS}\""
        VERSION_H_CONTENT_NEW
        ${VERSION_H_CONTENT})

    file(WRITE ${PROJECT_ROOT_DIR}/version.h ${VERSION_H_CONTENT_NEW})
endif()

if(WIN32)
    if(MSVC)
        add_definitions(-wd"4819")
    else()
        # do'nt using add_definitions for that when compile the .rc file the winres.exe will fail.
        # see the build directory CMakeFiles\xxx.dir\flags.make
        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
    endif()
else()
    add_definitions(
        -std=c++11
        -fvisibility=hidden
        )
endif()

add_subdirectory(src)
add_subdirectory(test)
